iT邦幫忙

2025 iThome 鐵人賽

DAY 30
0

來到鐵人賽最終回了,今天我們要讓「鏈結串列擁有第二層維度的記憶」。

💡 138.Copy List with Random Pointer 題目描述
給予一個特殊的鏈結串列,每個節點除了next外,還有一個random指標,它可以指向串列中的任何節點(或是 NULL)
請回傳這個鏈結串列的「深拷貝(deep copy)」,也就是建立一份完全獨立的新串列,其中每個節點的值和指標都正確複製。
範例如下
輸入:
Node1(val=7, random=NULL)
Node2(val=13, random=Node1)
Node3(val=11, random=Node5)
Node4(val=10, random=Node3)
Node5(val=1, random=Node1)
輸出:
新的鏈結串列結構相同,但節點為不同記憶體位址

🧩 解題思路
這題是「鏈結串列」的終極挑戰之一,因為它讓指標不再只有「下一個」,而是出現「平行的任意連結」。
換句話說,這題是「二維指標思維」的實戰!
🔍 解題關鍵一:建立原節點 → 新節點的映射表
我們可以用 unordered_map<Node*, Node*> 來記錄對應關係,確保每個原節點都能找到它的新節點版本:
unordered_map<Node*, Node*> map;
在第一次遍歷中,我們只負責建立節點與映射表:
Node* cur = head;
while (cur) {
map[cur] = new Node(cur->val);
cur = cur->next;
}
這樣就像先畫好「節點關係地圖」。
🔍 解題關鍵二:連結新節點的 next 與 random
第二次遍歷,開始用 map 把所有指標補上:
map[cur]->next = map[cur->next]
map[cur]->random = map[cur->random]
這樣每個新節點的 next 與 random 都會連到對應的新節點上。
cur = head;
while (cur) {
map[cur]->next = map[cur->next];
map[cur]->random = map[cur->random];
cur = cur->next;
}
到這裡,整個新串列的結構就完整重建了。
🔍 解題關鍵三:回傳新串列的頭節點
由於 map[head] 就是新鏈結串列的起點,我們只要回傳它即可完成深層複製。

🔁 解題步驟
1.第一次遍歷:複製節點(但不連線)
建立新節點(malloc),並將每個舊節點對應到新節點存入 map。
2.第二次遍歷:連接 next 與 random
用 map 取得對應的新節點,並設定:
new_node->next = map[old_node->next];
new_node->random = map[old_node->random];
3.回傳新串列的頭節點
https://ithelp.ithome.com.tw/upload/images/20251015/201694898EzM2Pyorl.png
https://ithelp.ithome.com.tw/upload/images/20251015/20169489qLc467Yk8m.png


上一篇
指標進階 2— 雙向鏈結串列
系列文
用leetcode系統化學習C語言30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言